一套关于构建可维护性的 CSS 的规范。

原文地址

一套关于构建可维护性的 CSS 的规范。

1.组件

考虑把 UI 图上的每一块都作为一个单独的组件。

1.1 组件命名

组件命名至少用两个单词,用中划线 - 链接,例如:

1.2 元素

元素是组成组件的一部分。

.search-form {
  > .field {/*...*/}
  > .action {/*...*/}
}
.article-card {
  .title {/*这是没有问题的*/}
  > .author {/*这是更好的写法*/}
}
.profile-box {
  > .firstname {/*...*/}
  > .lastname {/*...*/}
  > .avatar {/*...*/}
}
  .article-card {
  > h3    { /* 不要使用标签 */ }
  > .name { /* 这样很好 */ }
}

1.3 组件变化

组件可以有多种形式变化,组件的元素也可以有许多变化。

.like-button {
  &.-wide { /* ... */ }
  &.-short { /* ... */ }
  &.-disabled { /* ... */ }
}
.shopping-card {
  > .title { /* ... */ }
  > .title.-small { /* ... */ }
}

1.4 嵌套组件

有些时候组件嵌套是必要的,怎么更好的嵌套,这里有一些指南。

<div class="article-link">
  <div class="vote-box">...</div>
  <h3 class="title">...</h3>
  <p class="meta">...</p>
</div>
.article-header {
  > .vote-box > .up {
    /* ✗ avoid this */
  }
}

相反,更好的做法是将一个变种类添加到嵌套组件中,并在组件中修改其样式。

.vote-box {
  &.-highlight > .up {
    /* ... */
  }
}
<div class="search-form">
  <input class="input" type="text" />
  <button class="search-button -red -large"></button>
</div>

这时可以简化组件并使用 CSS 预处理器的继承机制:

<div class="search-form">
  <input class="input" type="text" />
  <button class="submit"></button>
</div>
.search-form {
  > .submit {
    @extend .search-button;
    @extend .search-button.-red;
    @extend .search-button.-large;
  }
}

1.5 布局

.article-list {
  & {
    @include clearfix;
  }

  > .article-card {
    width: 33.3%;
    float: left;
  }
}

.article-card {
  & {
    /* ... */
  }
  > .image {
    /* ... */
  }
  > .title {
    /* ... */
  }
  > .category {
    /* ... */
  }
}

1.6 工具类

._unmargin {
  margin: 0 !important;
}
._center {
  text-align: center !important;
}
._pull-left {
  float: left !important;
}
._pull-right {
  float: right !important;
}

2. CSS 结构

/* css/components/search-form.scss */
.search-form {
  > .button {
    /* ... */
  }
  > .field {
    /* ... */
  }
  > .label {
    /* ... */
  }

  // variants
  &.-small {
    /* ... */
  }
  &.-wide {
    /* ... */
  }
}
@import "components/* */";
/* ✗ Avoid: 3 levels of nesting */
.image-frame {
  > .description {
    /* ... */

    > .icon {
      /* ... */
    }
  }
}
/* ✓ Better: 2 levels */
.image-frame {
  > .description {
    /* ... */
  }
  > .description > .icon {
    /* ... */
  }
}

3.笔记

<article class="article-link">
  <div class="vote-box">
    <button class="up"></button>
    <button class="down"></button>
    <span class="count">4</span>
  </div>

  <h3 class="title">Article title</h3>
  <p class="count">3 votes</p>
</article>
.article-link {
  > .title {
    /* ... */
  }
  > .count {
    /* ... (!!!) */
  }
}

.vote-box {
  > .up {
    /* ... */
  }
  > .down {
    /* ... */
  }
  > .count {
    /* ... */
  }
}

在上面这个例子中,如果 .article-link > .count 没有这个子选择器,那这个样式也会应用到
.vote-box .count 上,这也是我们为什么要使用子选择器的原因。

  .alert-box {
  }
  .alert-card {
  }
  .alert-block {
  }

或者行内组件的命名:

  .link-button {
  }
  .link-span {
  }

4.总结

2016-07-04